﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TSOL.FastSPWeb.ValueObjects;
using System.Threading;
using Microsoft.SharePoint;

namespace TSOL.FastSPWeb.Core
{
    internal partial class FastSPItemUpdateThreadWorkerQueue 
    {
        internal void StopQueue()
        {
            lock (locker)
            {
                taskQ.Enqueue(new FastSPItemQueueClass()
                {
                    Action = FastUpdateAction.StopQueue,
                    UserUniqueID = null,
                    UserToken = null,
                    SiteGuid = Guid.Empty,
                    WebGuid = Guid.Empty,
                    ListGuid = Guid.Empty,
                    Item = null,
                });
                Monitor.Pulse(locker);
            }
        }
        internal Guid QueueUpdate(SPList List, SPItem Item)
        {
            Guid SiteGuid = List.ParentWeb.Site.ID;
            Guid WebGuid = List.ParentWeb.ID;
            SPUser CurrentSPUser = List.ParentWeb.CurrentUser;



            Guid _actionID = Guid.NewGuid();
            lock (locker)
            {
                taskQ.Enqueue(new FastSPItemQueueClass() 
                        { 
                          UserUniqueID = CurrentSPUser.LoginName.GetHashCode().ToString(), 
                          UserToken = List.ParentWeb.Site.SystemAccount.UserToken.CompareUser(CurrentSPUser.UserToken) ? 
                                                null :
                                                CurrentSPUser.UserToken,
                          SiteGuid = SiteGuid,
                          WebGuid = WebGuid, 
                          ListGuid = List.ID,
                          Item = Item,
                          Action = FastUpdateAction.Update,
                          ActionID = _actionID
                        });
                Monitor.Pulse(locker);
            }
            return _actionID;
        }

        internal void UpdateSPItem(FastSPItemQueueClass updateItem) {

            int internalUpdateTries = 0;
            bool updateDone = false;
            List<Exception> ActionException = new List<Exception>();

            while (updateDone == false && internalUpdateTries < FastSPWebThreadWorkerQueue.GlobalSPItemUpdateThreadWorkerQueue.UpdateTries)
            {
                try
                {
                    if (updateItem.UserToken == null)
                    {
                        FastSPWebCall.OpenElevatedWeb(updateItem.SiteGuid, updateItem.WebGuid,
                            (_site, _web, hashCode) =>
                            {
                                _web.FastLists(FastSPWebCallExtensions.CachePolicy.FastSPDefault, (Lists) =>
                                {
                                    SPList _list = null;
                                    _list = Lists[updateItem.ListGuid];
                                    SPItem _item = null;
                                    _list.FastItems(FastSPWebCallExtensions.CachePolicy.FastSPDefault, (Items) =>
                                    {
                                        _item = Items[updateItem.Item.ID];
                                        _item = updateItem.Item;
                                        _item.Update();
                                    });
                                });
                            });
                    }
                    else
                    {
                        FastSPWebCall.OpenWeb(updateItem.UserUniqueID, updateItem.UserToken, updateItem.SiteGuid, updateItem.WebGuid,
                            (_site, _web, hashCode) =>
                            {
                                _web.FastLists(FastSPWebCallExtensions.CachePolicy.FastSPDefault, (Lists) =>
                                {
                                    SPList _list = null;
                                    _list = Lists[updateItem.ListGuid];
                                    SPItem _item = null;
                                    _list.FastItems(FastSPWebCallExtensions.CachePolicy.FastSPDefault, (Items) =>
                                    {
                                        _item = Items[updateItem.Item.ID];
                                        _item = updateItem.Item;
                                        _item.Update();
                                    });
                                });
                            });
                    }
                    updateDone = true;
                }
                catch (Exception exception)
                {
                    ActionException.Add(exception);
                    internalUpdateTries++;
                }
            }

            if (!updateDone)
            {
                lock (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.UpdateExceptionDictionary)
                {
                    FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.UpdateExceptionDictionary.Add(
                            updateItem.ActionID,
                            new FastSPUpdateExceptionEntity
                            {
                                Action = updateItem.Action,
                                ActionExceptionList = ActionException,
                                ActionID = updateItem.ActionID,
                                Item = updateItem.Item,
                                ListGuid = updateItem.ListGuid,
                                SiteGuid = updateItem.SiteGuid,
                                UserToken = updateItem.UserToken,
                                UserUniqueID = updateItem.UserUniqueID,
                                WebGuid = updateItem.WebGuid
                            });
                }
            }
        }
    }
}
